﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;
using GrainManage.Data.Access;
using GrainManage.Entities;
using GrainManage.Data.Service;
using GrainManage.Server.Factory;
using System.Data;
using System.Text;
using System.Reflection;
using Newtonsoft.Json;
using GrainManage.Server.Business;
using GrainManage.Data.Model.Table;

namespace GrainManage.Server.Controllers
{
    public class BaseController : Controller
    {
        protected override void OnActionExecuting(ActionExecutingContext filterContext)
        {
            test();
            base.OnActionExecuting(filterContext);
            int stateCode = ExecuteFilter(filterContext);
            if (stateCode > 0)
            {
                var result = new BaseOutputModel();
                try
                {
                    BaseBusiness.SetResponse(stateCode, result);
                }
                catch (Exception e)
                {
                    BaseBusiness.SetResponse(StatusCode.Failed, result, e.Message);
                }
                finally
                {
                    filterContext.Result = Json(result, JsonRequestBehavior.AllowGet);
                }
            }
        }

        protected static string Serialize(object model, bool canBrowser = false)
        {
            var result = string.Empty;
            if (model != null)
            {
                if (canBrowser)
                {
                    if (System.Web.HttpContext.Current.Request.Browser.Browser != "Unknown")
                    {
                        var isoDate = new Newtonsoft.Json.Converters.IsoDateTimeConverter();
                        isoDate.DateTimeFormat = "yyyy-MM-dd hh:mm:ss";
                        result = "<pre>" + JsonConvert.SerializeObject(model, Formatting.Indented, isoDate) + "</pre>";
                    }
                    else
                    {
                        result = JsonConvert.SerializeObject(model, Formatting.Indented);
                    }
                }
                else
                {
                    result = JsonConvert.SerializeObject(model);
                }

            }
            return result;
        }

        protected static T Deserialize<T>(string jsonString)
        {
            T result = default(T);
            if (!string.IsNullOrEmpty(jsonString))
            {
                result = JsonConvert.DeserializeObject<T>(jsonString);
            }
            return result;
        }

        protected string GetInfo<TController, TBusiness>(TController controller, TBusiness business)
        {
            return GrainManage.Server.Tool.ApiUtil.GetApiInfo<TController, TBusiness>(false);
        }

        protected string GetSchema<TController, TBusiness>(TController controller, TBusiness business)
        {
            return GrainManage.Server.Tool.ApiUtil.GetApiInfo<TController, TBusiness>(true);
        }

        protected static void DebugForPost<InputParameter, OutputParameter>(System.Reflection.MethodBase method, Exception e, InputParameter input, OutputParameter output)
        {
            if (LogUtil.CanWrite(LogLevel.Debug))
            {
                var message = LogUtil.GetMessage(method, e, input, output, "POST");
                LogUtil.Write(message, LogLevel.Debug);
            }
        }

        protected static void DebugForGet(System.Reflection.MethodBase method, Exception e, params object[] input)
        {
            if (LogUtil.CanWrite(LogLevel.Debug))
            {
                var message = LogUtil.GetMessage<object[], object>(method, e, input, null, "GET");
                LogUtil.Write(message, LogLevel.Debug);
            }
        }

        private static int ExecuteFilter(ActionExecutingContext filterContext)
        {
            int stateCode = -1;
            try
            {
                if (filterContext.HttpContext.Request.RequestType == "POST")
                {
                    if (!filterContext.ActionParameters.ContainsKey("input"))
                    {
                        stateCode = StatusCode.InvalidInput;
                    }
                    else if (filterContext.ActionDescriptor.ControllerDescriptor != null)
                    {
                        var input = filterContext.ActionParameters["input"] as BaseInputModel;
                        if (input != null)
                        {
                            if (input.Authentication == null || string.IsNullOrEmpty(input.Authentication.UserName))
                            {
                                stateCode = StatusCode.NameEmpty;
                            }
                            else
                            {
                                var service = ObjectFactory.AccountService;
                                var account = service.GetAccountView(input.Authentication.UserName);
                                if (account == null)
                                {
                                    stateCode = StatusCode.NameNotExist;
                                }
                                else
                                {
                                    if (string.IsNullOrEmpty(input.Authentication.Guid) || account.Guid != input.Authentication.Guid)
                                    {
                                        stateCode = StatusCode.IdentityFailed;
                                    }
                                    else if (!account.IsOnLine)
                                    {
                                        stateCode = StatusCode.NotLogin;
                                    }

                                    if (account.CheckLoginIP)
                                    {
                                        if (account.LoginIP != GrainManage.Server.Tool.IPUtil.RequestHostAddress)
                                        {
                                            stateCode = StatusCode.IPChanged;
                                        }
                                    }

                                    input.PermissionID = account.PermissionID;
                                }
                            }
                        }
                    }
                }
                else
                {
                    if (ObjectFactory.GetAppConfig("AllowGet") != "true")
                    {
                        stateCode = StatusCode.GetNotAllowed;
                    }
                }
            }
            catch (Exception)
            {
                stateCode = StatusCode.Failed;
            }
            return stateCode;
        }

        private void test()
        {
            //var json = new System.Web.Script.Serialization.JavaScriptSerializer();
            //var str = json.Serialize(new GrainManage.Entities.Account.InputGetEncryptKey { AccountName = "bijinshu", EncryptModel = 3, MyProperty = GrainManage.Entities.Encrypt.EncryptModel.MD5 });
            //var obj1 = json.Deserialize<GrainManage.Entities.Account.InputGetEncryptKey>(str);
            //var obj2 = json.Deserialize(str, typeof(GrainManage.Entities.Account.InputGetEncryptKey));
            //var obj3 = json.DeserializeObject(str);
            //var s1 = "abc";
            //var s2 = "你好啊,藏獒!";
            //var s3 = "咬";
            //var b1 = ASCIIEncoding.ASCII.GetBytes(s1);
            //var b2 = ASCIIEncoding.ASCII.GetBytes(s2);
            //var b3 = ASCIIEncoding.ASCII.GetBytes(s3);

            //var b4 = Encoding.Unicode.GetBytes(s1);
            //var b5 = Encoding.Unicode.GetBytes(s2);
            //var b6 = Encoding.Unicode.GetBytes(s3);

            //var b7 = Encoding.UTF8.GetBytes(s1);
            //var b8 = Encoding.UTF8.GetBytes(s2);
            //var b9 = Encoding.UTF8.GetBytes(s3);
            //byte padValue = Convert.ToByte('a');
            //byte b1 = Encoding.UTF8.GetBytes("a")[0];
            //byte b2 = Encoding.Unicode.GetBytes("a")[0];


            //using (var desCrypto = System.Security.Cryptography.DESCryptoServiceProvider.Create() as System.Security.Cryptography.DESCryptoServiceProvider)
            //{
            //    string s1 = Convert.ToBase64String(desCrypto.Key);
            //    string s2 = Encoding.UTF8.GetString(desCrypto.Key);
            //    string s3 = Encoding.UTF7.GetString(desCrypto.Key);
            //    string s4 = Encoding.UTF32.GetString(desCrypto.Key);
            //    string s5 = Encoding.Unicode.GetString(desCrypto.Key);
            //    string s6 = Encoding.Default.GetString(desCrypto.Key);
            //    string s7 = Encoding.BigEndianUnicode.GetString(desCrypto.Key);
            //    string s8 = Encoding.ASCII.GetString(desCrypto.Key);
            //}
        
        }
    }
}
